#include "bot.h"
Bot* Bot::_instance= NULL;
Bot* Bot::getInstance() {
	if(_instance == NULL){
		_instance = new Bot();
        return _instance;
    }
    else{
        return _instance;
    }
}
Bot::Bot()
{
	_allEntries = EntriesManager::getInstance();
	//getDefaultView();
}

Bot::~Bot()
{
	//delete _instance;
}

CommonUtils::ReturnStatus Bot::getDefaultView() {
	return _allEntries->displayCommand();
}
//Comments:

//TO MAY: SHOuld all tokeniser functions pass strings by reference, if not there must be some
//			way or mechanism to update the string after its been put through istringstream!


//TO JH: DisplayCmd should have 3 types, display all, display tasks, display events. For now.
//		Will expand to display 7 days, display all days, display month
//		DONE:The static I have no idea how to resolve for the tokeniser... hmmm.. help settle this too.

//End of Comments
vector<Entry*> Bot::getVector() {
	return _allEntries->getActive();
}
void Bot::editFromGui(int row, int col, QVariant value) {
	_allEntries->guiEdit(row, col, value);
}
CommonUtils::ReturnStatus Bot::executeCommand(string userCommand){

	CommonUtils::ReturnStatus output;

	//first call to tokenizer to extract first command
	CommonUtils::COMMAND_TYPE command = Tokeniser::extractCommand(userCommand); //Theres problem in tokeniser class tho

	//Will refactor with enum next time
	try {
		switch(command) {
			case CommonUtils::COMMAND_ADD:{
				Entry* entry = Tokeniser::extractEntry(userCommand);
				output = _allEntries->addCommand(entry);
				break;
			}
			case CommonUtils::COMMAND_DELETE:{
				int lineToDel = Tokeniser::extractLineNum(userCommand);
				output = _allEntries->deleteCommand(lineToDel);
				break;
			}
			
			case CommonUtils::COMMAND_SET_DONE:{
				int lineToDel = Tokeniser::extractLineNum(userCommand);
				output = _allEntries->setDoneCommand(lineToDel);
				break;
			}
			case CommonUtils::COMMAND_EDIT:{
				int lineToEdit = Tokeniser::extractLineNum(userCommand);
				//vector<string> newEntry(5, "");
				vector<string> newEntry = Tokeniser::extractEntryToEdit(userCommand);
				//Entry* entry = Tokeniser::extractEntryToEdit(userCommand); //function is special for editing purposes
				output = _allEntries->editCommand(lineToEdit, newEntry);
				break;
			}
			case CommonUtils::COMMAND_DISPLAY:{
				//string typeOfEntry = Tokeniser::extractTypeToDisplay(userCommand); //may need to have a function to extract Type
				output = _allEntries->displayCommand(); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_ALL:{
				//string typeOfEntry = Tokeniser::extractTypeToDisplay(userCommand); //may need to have a function to extract Type
				output = _allEntries->displayCommand(true); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_SORT:{
				output = _allEntries->sortCommand(); //Jh, your code not written for this! Ur head.
				break;
			}
			case CommonUtils::COMMAND_SEARCH:{
				string key = Tokeniser::extractKey(userCommand); 
				output = _allEntries->searchCommand(key, 0);
				break;
			}
			case CommonUtils::COMMAND_UNDO:{
				//string key = Tokeniser::extractString(userCommand); 
				output = _allEntries->undoCommand();
				break;
			}
			case CommonUtils::COMMAND_REDO:{
				//string key = Tokeniser::extractString(userCommand); 
				output = _allEntries->redoCommand();
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_TASK:{	
				//string typeOfEntry = Tokeniser::extractTypeToDisplay(userCommand); //may need to have a function to extract Type
				output = _allEntries->searchTasks(); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_EVENT:{
				//string typeOfEntry = Tokeniser::extractTypeToDisplay(userCommand); //may need to have a function to extract Type
				output = _allEntries->searchEvents(); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_WEEK: {
				//string typeOfEntry = Tokeniser::extractTypeToDisplay(userCommand); //may need to have a function to extract Type
				output = _allEntries->searchWeek(); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_DAY: {
				string key = Tokeniser::extractKey(userCommand);
				QDate target = Tokeniser::formatDate(key);
				output = _allEntries->searchDay(target); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_DAY_BEFORE: {
				string key = Tokeniser::extractKey(userCommand);
				QDate target = Tokeniser::formatDate(key);
				output = _allEntries->searchDay(target,1); //JH, i need your display cmd to be able to display accordingly
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_PAST_NOT_DONE: {
				string key = Tokeniser::extractKey(userCommand);
				QDate target = Tokeniser::formatDate(key);
				_allEntries->displayCommand();
				if(target.isValid()) {
					_allEntries->searchStatus();
					output = _allEntries->searchDay(target, 1);
				} else
					output = getDefaultView();
				break;
			}
			case CommonUtils::COMMAND_CLEAR: {
				output = _allEntries->clearCommand();
				break;
			}		
			case CommonUtils::COMMAND_DISPLAY_DONE: {
				output = _allEntries->searchStatus(1);
				break;
			}
			case CommonUtils::COMMAND_DISPLAY_NOT_DONE: {
				output = _allEntries->searchStatus();
				break;
			}
			case CommonUtils::COMMAND_EXIT: {
				exit(0);
				break;
			}
			case CommonUtils::COMMAND_INVALID:
			default:{
				throw BotException(BotException::EXCEPTION_COMMAND_INVALID);
			}
		}
	}
	

	//Testing out emitting of signals
	/*QDate addDate(2014,2,25 );
	emit updateEntry(addDate);*/

	catch (BotException& e) {
		output.statusMsg=e.what();
	}
	return  output;
}
CommonUtils::ReturnCount Bot::getCount(){
	return _allEntries->getCount();
}